package com.mxl.service.channel.impl;

import java.text.DecimalFormat;
import java.text.ParseException;
import java.util.Date;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import com.mxl.common.helper.OrderStatus;
import com.mxl.common.helper.ResponseType;
import com.mxl.common.helper.ResultStatus;
import com.mxl.dao.channel.ChannelGatewayRelationDao;
import com.mxl.dao.channel.DealRequestDao;
import com.mxl.dao.channel.DealResponseDao;
import com.mxl.dao.channel.model.ChannelGatewayRelation;
import com.mxl.dao.channel.model.DealRequest;
import com.mxl.dao.channel.model.DealResponse;
import com.mxl.service.channel.CommCallbackProcessService;
import com.mxl.service.channel.CommCallbackRequest;
import com.mxl.service.channel.comm.CommStatusProcess;
import com.mxl.service.dto.ChargeResponse;

@Service("commCallbackProcessService")
public class CommCallbackProcessServiceImpl implements
		CommCallbackProcessService {
	private static final Logger logger = LoggerFactory
			.getLogger(CommCallbackProcessServiceImpl.class);

	@Resource(name = "dealRequestDao")
	private DealRequestDao dealRequestDao;

	@Resource(name = "commStatusProcess")
	private CommStatusProcess commStatusProcess;

	@Resource(name = "dealResponseDao")
	private DealResponseDao dealResponseDao;

	@Resource(name = "channelGatewayRelationDao")
	private ChannelGatewayRelationDao channelGatewayRelationDao;

	public String process(CommCallbackRequest request) {
		String handlerStatus = "N";
		DealRequest dealRequest = dealRequestDao.queryRequestBySeqNo(request
				.getOrderID());
		if (dealRequest.getStatus() == OrderStatus.SUCC.getValue()
				|| dealRequest.getStatus() == OrderStatus.FAIL.getValue()) {
			logger.info("order is complete, seqno is : {}",
					request.getOrderID());
			handlerStatus = "Y";
		} else {
			DealResponse dealResponse = buildResponse(request, dealRequest);
			dealResponseDao.saveResponse(dealResponse);
			// 去错误吗关系表查询关系
			ChannelGatewayRelation channelGatewayRelation = channelGatewayRelationDao
					.getGatewayCodeByChannelAndCode(
							dealRequest.getChannelCode(), 0,
							dealResponse.getErrorCode());
			if (channelGatewayRelation == null) {
				logger.info(
						"Callback handler strategy is undefine, respcode is :{},,,, {}",
						dealRequest.getChannelCode(),
						dealResponse.getErrorCode());
			} else {
				// 设置状态
				ChargeResponse response = new ChargeResponse();
				response.setChannelCode(dealRequest.getChannelCode());
				response.setErrorCode(channelGatewayRelation
						.getSystemErrorCode());
				response.setFinishTime(new Date());
				response.setPayMoney(dealResponse.getDealAmount());
				response.setSeqNo(request.getOrderID());
				response.setStatus(channelGatewayRelation.getStatus());
				response.setStrategyCode(channelGatewayRelation
						.getStrategyCode());

				dealRequest.setDealAmount(dealResponse.getDealAmount());
				dealRequest.setLastUpdate(new Date());
				if (channelGatewayRelation.getStatus() == ResultStatus.SUCC
						.getValue()) {
					dealRequest.setStatus(OrderStatus.SUCC.getValue());
				} else if (channelGatewayRelation.getStatus() == ResultStatus.FAIL
						.getValue()) {
					dealRequest.setStatus(OrderStatus.FAIL.getValue());
				} else {
					logger.info(
							"Callback handler strategy is channelGatewayRelation not result, respcode is : {},,{}",
							dealResponse.getResCode(),
							dealRequest.getChannelCode());
					return "N";
				}
				dealRequestDao.updateRequest(dealRequest);
				// 放到队列中--往上修改状态-金额等信息
				commStatusProcess.dispatch(response);
				handlerStatus = "Y";
			}
		}
		return handlerStatus;
	}

	private DealResponse buildResponse(CommCallbackRequest request,
			DealRequest dealRequestDTO) {
		DealResponse dealResponseDTO = new DealResponse();
		dealResponseDTO.setCreationDate(new Date());
		try {
			DecimalFormat df = new DecimalFormat("#");
			dealResponseDTO.setDealAmount(df.parse(request.getPayMoney())
					.longValue() * 100);
		} catch (ParseException e) {
			dealResponseDTO.setDealAmount(0L);
			logger.error("buildResponse ParseException", e);
		}
		dealResponseDTO.setRequestId(dealRequestDTO.getId());
		dealResponseDTO.setResCode(request.getState() + "|"
				+ request.getErrcode());
		dealResponseDTO.setErrorCode(request.getErrcode());
		dealResponseDTO.setRemoteFlg(ResponseType.CALLBACK_RESPONSE.getValue());
		dealResponseDTO.setResContentval(request.getCallBackContent());
		dealResponseDTO.setSeqId(request.getSeqId());
		dealResponseDTO.setSettleAmount(request.getChargeMoney());
		return dealResponseDTO;
	}

}
